//
//  ViewController.m
//  DesignPreview
//
//  Created by yxb on 13-1-4.
//  Copyright (c) 2013年 um. All rights reserved.
//

#import "ViewController.h"

#include <errno.h>       /* obligatory includes */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>

@interface ViewController () {
    int client_sock, server_sock;
}
@property (nonatomic, retain, readwrite) IBOutlet UIImageView* image;
@property (nonatomic, retain, readwrite) IBOutlet UILabel* label;
@property (nonatomic, retain, readwrite) UIImage* buffed_image;
-(void) ShowMsg:(NSString*) msg;
-(void) HideMsg;
-(void) UpdateImage:(UIImage*) image;
-(void) ServerThreadMain;
-(int) createServerSocket;
-(int) acceptClient:(int) server_sock;
-(void) closeSocket;
@end

@implementation ViewController
@synthesize image = _image;
@synthesize label = _label;
@synthesize buffed_image = _buffed_image;

-(id) init
{
    self = [super init];
    if (self) {
        server_sock = 0;
        client_sock = 0;
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self ShowMsg:@"N/A"];
    [self performSelectorInBackground:@selector(ServerThreadMain) withObject:self];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - UI operation
-(void) HideMsg
{
    self.label.hidden = true;
    NSLog(@"%@[hidden]", self.label.text);
}

-(void) ShowMsg:(NSString*) msg
{
    NSLog(@"%@",msg);
    self.label.text = msg;
    self.label.hidden = false;
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(HideMsg) object:nil];
    [self performSelector:@selector(HideMsg) withObject:nil afterDelay:2.5];
}

-(void) UpdateImage:(UIImage*) image
{
    if (image == nil) {
        NSLog(@"image is nil");
        return;
    }
    [self.image setImage:image];
//    NSLog(@"draw image %@", image);
}

#pragma mark - Network Thread
-(void) ServerThreadMain
{
    @synchronized(self) {
        if (server_sock == 0 && client_sock == 0) {
            client_sock = 1;
        } else {
            NSLog(@"server_sock has already created.");
            return;
        }
    }
//    while (true)
    {
        [self ShowMsg:@"Create Server"];
        
        [NSThread sleepForTimeInterval:3];
        [self ShowMsg:@"ServerThreadMain"];
        server_sock = [self createServerSocket];
        if (server_sock<0) {
            return;
        }
        
        [self ShowMsg:@"Waitting for Connection"];
        client_sock = [self acceptClient:server_sock];
        if (client_sock<0) {
            return;
        }
        [self ShowMsg:@"Connected"];
        
//        CGrect screenBounds = [ [UIScreen mainScreen]bounds];//返回的是带有状态栏的Rect 
        CGRect viewBounds = [ [UIScreen mainScreen]applicationFrame];//返回的是不带状态栏的Rect
        
        while (true) {
            [NSThread sleepForTimeInterval:0.05];
            int32_t offsetX = 0, offsetY = 0, Width = htonl(viewBounds.size.width), Height = htonl(viewBounds.size.height);
            
            write(client_sock, &offsetX, sizeof(int32_t));
            write(client_sock, &offsetY, sizeof(int32_t));
            write(client_sock, &Width, sizeof(int32_t));
            write(client_sock, &Height, sizeof(int32_t));
            
            int32_t fileSize = 0;
            int32_t readlen = read(client_sock, &fileSize, sizeof(int32_t));
            fileSize = ntohl(fileSize);
//            NSLog(@"Read:%i", fileSize);
            
            if (fileSize<0 || readlen<=0) {
                [self ShowMsg:@"Error read data"];
                break;
            }
            
            char* buff = (char*) malloc(fileSize);
            int32_t readed = 0;
            readlen = read(client_sock, buff+readed, fileSize-readed);
            if (readlen<=0) {
                [self ShowMsg:@"Error read data"];
                free(buff);
                goto end;
            }
            readed += readlen;
            while (readed < fileSize) {
                readlen = read(client_sock, buff+readed, fileSize-readed);
                if (readlen<=0) {
                    [self ShowMsg:@"Error read data"];
                    free(buff);
                    goto end;
                }
                readed += readlen;
            }
        
            NSData* data = [NSData dataWithBytes:buff length:fileSize];
            UIImage* bimage = [UIImage imageWithData:data];
            [self performSelectorOnMainThread:@selector(UpdateImage:) withObject:bimage waitUntilDone:NO];
            [bimage release];
            [data release];
            free(buff);
        }
    end:
        [self ShowMsg:@"Disconnected"];
        [self closeSocket];
    }
}

#define PORT_DEVICE 7800
-(int) createServerSocket
{
    int    s;
    struct sockaddr_in sa;
    
    memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
    sa.sin_family= AF_INET;              /* this is our host address */
    sa.sin_port= htons(PORT_DEVICE);                /* this is our port number */
    if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
    {
        [self ShowMsg:@"SOCKET CREATE ERROR"];
        return(-1);
    }
    if (bind(s, (const struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0) {
        close(s);
        [self ShowMsg:@"BIND ERROR"];
        return(-1);                               /* bind address to socket */
    }
    listen(s, 3);                               /* max # of queued connects */
    return(s);
}

-(int) acceptClient:(int) _server_sock
{
    int t;                  /* socket of connection */
    if ((t = accept(_server_sock, NULL, NULL)) < 0)   /* accept connection if there is one */
    {
        [self ShowMsg:@"ACCEPT ERROR SOCKET"];
        return(-1);
    }
    return(t);
}

-(void) closeSocket
{
    if (server_sock) {
        close(server_sock);
        server_sock = 0;
    }
    if (client_sock) {
        close(client_sock);
        client_sock = 0;
    }
    
   
}

@end
